package sg.edu.nus.iss.billing.vo.subscription;

import java.util.ArrayList;
import sg.edu.nus.iss.billing.common.DbUtil;
import sg.edu.nus.iss.billing.common.Util;
import sg.edu.nus.iss.billing.common.exception.InvalidParamsException;
import sg.edu.nus.iss.billing.vo.subscription.feature.ChannelFeatureVO;
import sg.edu.nus.iss.billing.vo.subscription.feature.StandardChannelFeatureVO;

public class CableTvVO extends SubscriptionVO {

	private ArrayList<StandardChannelFeatureVO> standardChannels = new ArrayList<StandardChannelFeatureVO>();
	private ArrayList<ChannelFeatureVO> addonChannels = new ArrayList<ChannelFeatureVO>();
	
	public CableTvVO() {
		setSubsId(Util.Default_NULL);
		setAccNo(Util.Default_NULL);
		setName(Util.SUBSCRIPTIONVO_CABLETV);
		setStartDate(Util.getNullDate());
		setEndDate(Util.getNullDate());
		setMonthlySuscription(0);
		setStatus(Util.ACCOUNT_STATUS_INACTIVE);
		setDescription(Util.Default_NULL);
		addStandardChannel(new StandardChannelFeatureVO());
		addStandardChannel(new StandardChannelFeatureVO());
		addStandardChannel(new StandardChannelFeatureVO());
	}
	
	public ArrayList<StandardChannelFeatureVO> get3StandardChannels() {
		return standardChannels;
	}

	public void addStandardChannel(StandardChannelFeatureVO channel) {
		if (standardChannels.size() == 3) {
			standardChannels.remove(0);
		}
		standardChannels.add(channel);
	}
	
	public void updateStandardChannel(StandardChannelFeatureVO channel) {
		for (int j = 0; j < standardChannels.size(); j++) {
			if (standardChannels.get(j).getChannelCode().equals(channel.getChannelCode())) {
				standardChannels.set(j, channel);
			}
		}
	}
	
	public void removeStandardChannel(StandardChannelFeatureVO channel) {
		for (int j = 0; j < standardChannels.size(); j++) {
			if (standardChannels.get(j).getChannelCode().equals(channel.getChannelCode())) {
				standardChannels.remove(j);
			}
		}
	}

	public ArrayList<ChannelFeatureVO> getAllAddonChannel() {
		return addonChannels;
	}
	
	public void setAddonChannel(ArrayList<ChannelFeatureVO> addonChannels) {
		this.addonChannels= addonChannels;
	}
	
	public void addChannel(ChannelFeatureVO channel) {
		addonChannels.add(channel);
	}
	
	public void updateChannel(ChannelFeatureVO channel) {
		for (int j = 0; j < addonChannels.size(); j++) {
			if (addonChannels.get(j).getChannelCode().equals(channel.getChannelCode())) {
				addonChannels.set(j, channel);
			}
		}
	}
	
	public void removeChannel(ChannelFeatureVO channel) {
		for (int j = 0; j < addonChannels.size(); j++) {
			if (addonChannels.get(j).getChannelCode().equals(channel.getChannelCode())) {
				addonChannels.remove(j);
			}
		}
	}
	
	@Override
	public void setParameters(String serialisedEntry)
			throws InvalidParamsException {

		String[] tokens =  serialisedEntry.split(java.util.regex.Pattern.quote(DbUtil.DELIMITER));
		if (tokens.length <8 ) {
			throw new InvalidParamsException("Expected 6 or more parameters, received " + tokens.length);
		} else {
		
			setAccNo(tokens[0]);
			setSubsId(tokens[1]);
			setName(tokens[2]);
			setStartDate(Util.getDateFromString(tokens[3]));
			setEndDate(Util.getDateFromString(tokens[4]));
			setMonthlySuscription(Double.parseDouble(tokens[5]));
			setStatus(tokens[6]);
			setDescription(tokens[7]);
			
			if (tokens.length >23) {

				// Set main channel
				int tkCnt = 8;
				for (int i=0; i<3; i++) {
					StringBuilder sb = new StringBuilder();
					sb.append(tokens[tkCnt]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[tkCnt+1]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[tkCnt+2]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[tkCnt+3]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[tkCnt+4]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[tkCnt+5]);
					StandardChannelFeatureVO channel = new StandardChannelFeatureVO();
					channel.setParameters(sb.toString());
					addStandardChannel(channel);
					tkCnt += 6;
				}
				
				// set add-on channels
				int cnt = Integer.parseInt(tokens[26]);
				int scCnt = 27;
				for (int i=0; i<cnt; i++) {
					StringBuilder sb = new StringBuilder();
					sb.append(tokens[scCnt]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[scCnt+1]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[scCnt+2]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[scCnt+3]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[scCnt+4]);
					sb.append(DbUtil.DELIMITER);
					sb.append(tokens[scCnt+5]);
					
					try {
						ChannelFeatureVO ch;
						ch = (ChannelFeatureVO) Util.getFeatureVOMap().get(tokens[scCnt]).newInstance();
						ch.setParameters(sb.toString());
						addChannel(ch);
					} catch (InstantiationException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
					scCnt+=6;
				}
			}
		}
	}

	@Override
	public String serialised() {
		StringBuilder sb = new StringBuilder();
		sb.append(getAccNo());
		sb.append(DbUtil.DELIMITER);
		sb.append(getSubsId());
		sb.append(DbUtil.DELIMITER);
		sb.append(getName());
		sb.append(DbUtil.DELIMITER);
		sb.append(Util.getFormattedDate(getStartDate()));
		sb.append(DbUtil.DELIMITER);
		sb.append(Util.getFormattedDate(getEndDate()));
		sb.append(DbUtil.DELIMITER);
		sb.append(getMonthlySuscription());
		sb.append(DbUtil.DELIMITER);
		sb.append(getStatus());
		sb.append(DbUtil.DELIMITER);
		sb.append(getDescription());
		
		for (int i=0; i<standardChannels.size(); i++) {
			sb.append(DbUtil.DELIMITER);
			sb.append(standardChannels.get(i).serialised());
		}
		
		sb.append(DbUtil.DELIMITER);
		sb.append(addonChannels.size());
		for (int i=0; i<addonChannels.size(); i++) {
			sb.append(DbUtil.DELIMITER);
			sb.append(addonChannels.get(i).serialised());
		}
		
		return sb.toString();
	}

	public void clearChannels() {
		addonChannels.clear();
		standardChannels.clear();
	}
}
